package com.example.demo.web.rest.util;

import com.example.demo.domain.Sso;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author shiwq
 * @date 2021/10/25 11:06
 * @describe
 */
public class SsoUtil {

    private static String SEP_PATH = "<<";

    public SsoUtil() {
    }

    private static byte HEXToByte(String hex) {
        return Integer.valueOf(hex, 16).byteValue();
    }

    private static int HEXToInt(String hex) {
        return Integer.valueOf(hex, 16);
    }

    private static final String byteHEX(byte ib) {
        char[] Digit = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] ob = new char[]{Digit[ib >>> 4 & 15], Digit[ib & 15]};
        String s = new String(ob);
        return s;
    }

    private static String bytesHEX(byte[] b) {
        StringBuffer s = new StringBuffer();

        for(int i = 0; i < b.length; ++i) {
            s.append(byteHEX(b[i]));
        }

        return s.toString();
    }

    private static boolean createFolder(String folder) {
        StringTokenizer tokens = new StringTokenizer(folder, "/\\", true);
        String path = "";
        boolean result = true;

        while(tokens.hasMoreTokens()) {
            path = path + tokens.nextToken();
            File f = new File(path);
            if (!f.exists()) {
                try {
                    f.mkdir();
                } catch (Exception var6) {
                    result = false;
                    var6.printStackTrace();
                }
            }
        }

        return result;
    }

    private static String encodeTime(String timeString) {
        String yearMonthDay = timeString.substring(0, 8);
        String hourMinuteSecond = timeString.substring(8);
        int c = 6 + (int)(Math.random() * 18.0D) + 65;
        String randC = (new Character((char)c)).toString();
        String result = toHEX(Integer.parseInt(yearMonthDay)) + randC + toHEX(Integer.parseInt(hourMinuteSecond));
        return result;
    }

    public static String getKey(int expired, String domain, String privateKey, String[] userinfo, String logpath) {
        String result = null;
        Sso sso = new Sso();
        String username = null;
        if (userinfo == null) {
            return null;
        } else {
            username = "";

            int i;
            for(i = 0; i < userinfo.length; ++i) {
                username = username + userinfo[i] + "<<";
            }

            if (i > 0) {
                username = username.substring(0, username.length() - SEP_PATH.length());
            }

            if (domain != null) {
                sso.setDomain(domain);
            }

            if (expired > 0) {
                sso.setExpired(expired);
            }

            if (username != null) {
                sso.setUsername(username);
            }

            if (privateKey != null) {
                sso.setPrivateKey(privateKey);
            }

            try {
                makeSsoKey(sso);
                result = sso.getSsoKey();
            } catch (Exception var10) {
                writeErr(logpath, var10);
            }

            return result;
        }
    }

    public static String getKey(int expired, String domain, String privateKey, String[] userinfo) {
        return getKey(expired, domain, privateKey, userinfo, (String)null);
    }

    public static String[] getUserInfo(String rand, String domain, String privateKey) throws Exception {
        String[] result = null;
        if (rand == null) {
            return result;
        } else {
            Sso sso = new Sso();
            if (domain != null) {
                sso.setDomain(domain);
            }

            if (privateKey != null) {
                sso.setPrivateKey(privateKey);
            }

            sso.setSsoKey(rand);
            validSsoKey(sso);
            result = split(sso.getUsername(), SEP_PATH);
            return result;
        }
    }

    public static void main(String[] args) {
        try {
            String rand = "63C1675DBE99CD31E03A62B15AFD47160A61646D696E1346555R24E52";
            System.out.println("rand is " + rand);
            String[] ard = getUserInfo(rand, "com.example.demo", "gatewaysso");

            for(int i = 0; i < ard.length; ++i) {
                System.out.println(i + " is " + ard[i] + "");
            }

            System.out.println(getKey(6000, "com.example.demo","fjydzhyy", ard));


        } catch (Exception var4) {
            var4.printStackTrace();
        }

    }

    private static String makeMD5(String source) throws Exception {
        if (source == null) {
            return "";
        } else {
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(source.getBytes());
                byte[] b = md.digest();
                String result = bytesHEX(b);
                return result;
            } catch (Exception var4) {
                var4.printStackTrace();
                throw new Exception("No found SsoKey by " + source);
            }
        }
    }

    private static void makeSsoKey(Sso model) throws Exception {
        String result = null;
        if (model.getUsername() == null) {
            throw new Exception("Username isn't defined");
        } else {
            result = model.getUsername() == null ? "" : model.getUsername();
            if (model.getDomain() == null) {
                throw new Exception("Domain isn't defined");
            } else {
                result = result + (model.getDomain() == null ? "" : model.getDomain());
                result = makeMD5(result);
                if (model.getPrivateKey() == null) {
                    throw new Exception("PrivateKey isn't defined");
                } else {
                    result = result + (model.getPrivateKey() == null ? "" : model.getPrivateKey());
                    result = makeMD5(result);
                    if (model.getMakeTime() == null) {
                        throw new Exception("MakeTime is not defined");
                    } else {
                        result = result + (model.getMakeTime() == null ? "" : model.getMakeTime());
                        result = makeMD5(result);
                        if (model.getUsername() != null) {
                            String hexUsername = bytesHEX(model.getUsername().getBytes("GBK"));
                            String lenHex = toHEX(hexUsername.length());
                            if (lenHex.length() <= 1) {
                                lenHex = "0" + lenHex;
                            }

                            result = result + lenHex + hexUsername;
                        }

                        result = result + encodeTime(model.getMakeTime());
                        model.setSsoKey(result);
                    }
                }
            }
        }
    }

    private static String[] split(String src, String delim) {
        String[] result = null;
        List list = new ArrayList();
        if (src == null) {
            return new String[0];
        } else {
            StringTokenizer tokens = new StringTokenizer(src, delim);

            while(tokens.hasMoreTokens()) {
                String token = tokens.nextToken();
                list.add(token);
            }

            result = new String[list.size()];

            for(int i = 0; i < list.size(); ++i) {
                result[i] = list.get(i).toString();
            }

            return result;
        }
    }

    private static String toHEX(int b) {
        return Integer.toHexString(b).toUpperCase();
    }

    private static void validSsoKey(Sso model) throws Exception {
        String ssoKey = model.getSsoKey();
        String _oldUsername = model.getUsername();
        String _oldMakeTime = model.getMakeTime();

        try {
            if (ssoKey == null) {
                throw new Exception("key is null!");
            }

            if (ssoKey.length() <= 34) {
                throw new Exception("key length is error!");
            }

            String _md5 = ssoKey.substring(0, 32);
            String _usernameLenHex = ssoKey.substring(32, 34);
            if (ssoKey.length() <= 34 + HEXToInt(_usernameLenHex)) {
                throw new Exception("key length is error!");
            }

            String _usernameHex = ssoKey.substring(34, 34 + HEXToInt(_usernameLenHex));
            String _dateHex = ssoKey.substring(34 + HEXToInt(_usernameLenHex));
            byte[] c = new byte[_usernameHex.length() / 2];

            for(int i = 0; i < _usernameHex.length(); i += 2) {
                c[i / 2] = HEXToByte(_usernameHex.substring(i, i + 2));
            }

            String username = new String(c);
            String date = "";

            for(int j = 0; j < _dateHex.length(); ++j) {
                char ch = _dateHex.charAt(j);
                if (ch > 'F') {
                    String _yearMonthDay = HEXToInt(_dateHex.substring(0, j)) + "";

                    for(int t = _yearMonthDay.length(); t < 8; ++t) {
                        _yearMonthDay = "0" + _yearMonthDay;
                    }

                    String _hourMinuteSecond = HEXToInt(_dateHex.substring(j + 1)) + "";

                    for(int t = _hourMinuteSecond.length(); t < 6; ++t) {
                        _hourMinuteSecond = "0" + _hourMinuteSecond;
                    }

                    date = _yearMonthDay + _hourMinuteSecond;
                    break;
                }
            }

            if (model.getUsername() == null) {
                model.setUsername(username);
            }

            if (model.getDomain() == null) {
                throw new Exception("Domain isn't defined");
            }

            if (model.getPrivateKey() == null) {
                throw new Exception("PrivateKey isn't defined");
            }

            if (model.getMakeTime().compareTo(date) > 0) {
                throw new Exception("Key is Expired");
            }

            model.setMakeTime(date);
            makeSsoKey(model);
            if (!model.getSsoKey().substring(0, 32).equals(_md5)) {
                throw new Exception("Valid Key fail");
            }
        } catch (Exception var16) {
            model.setUsername(_oldUsername);
            model.setMakeTime(_oldMakeTime);
            throw var16;
        }

    }

    private static void writeErr(String path, Object o) {
        writelog(path, o, 1);
    }

    private static void writeOut(String path, Object o) {
        writelog(path, o, 0);
    }

    private static void writelog(String path, Object o, int type) {
        if (o != null) {
            if (path != null) {
                if (createFolder(path)) {
                    Calendar cal = Calendar.getInstance();
                    String times = cal.get(1) + "" + (cal.get(2) > 9 ? cal.get(2) + "" : "0" + cal.get(2)) + "" + (cal.get(5) > 9 ? cal.get(5) + "" : "0" + cal.get(5));
                    if (type == 1) {
                        times = "sso_err_" + times + ".log";
                    }

                    if (type == 0) {
                        times = "sso_out_" + times + ".log";
                    }

                    String filename = path + File.separator + times;
                    if (path.endsWith("/") || path.endsWith("\\")) {
                        filename = path + times;
                    }

                    FileWriter out = null;

                    try {
                        out = new FileWriter(filename, true);
                        out.write("[" + cal.getTime().toString() + "]");
                        if (o instanceof Exception) {
                            ((Exception)o).printStackTrace(new PrintWriter(out));
                        }

                        if (o instanceof String) {
                            out.write((String)o);
                        }

                        out.write("\r\n");
                        out.flush();
                    } catch (Exception var17) {
                        var17.printStackTrace();
                    } finally {
                        try {
                            if (out != null) {
                                out.close();
                            }
                        } catch (Exception var16) {
                        }

                    }

                }
            }
        }
    }
}
